package design.mode.dispatcher.convert;

import org.dom4j.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ParseXmlUtil {
    /**
     * 将XML文档解析为Map
     * @param xmlStr XML字符串
     * @return 解析后得到的Map
     */
    public static Map<String,Object> xml2Map(String xmlStr) throws Exception{
        Document document = DocumentHelper.parseText(xmlStr);
        // 获取根节点
        Element rootElement = document.getRootElement();
        Map<String,Object> map = new HashMap<>();
        // 解析根节点
        traverseNode(rootElement,map);
        Map<String,Object> resultMap = new HashMap<>();
        return map;
    }

    /**
     * 递归遍历Node，并将Node解析为Map
     * @param element 要遍历的Element对象
     * @param map 要将Element解析为Map后存储的Map
     */
    private static void traverseNode(Element element, Map<String,Object> map) {
        // 获取节点名称
        String nodeName = element.getName();
        // 获取节点值
        String nodeValue = element.getTextTrim();
        // 获取节点属性
        List<Attribute> attributes = element.attributes();

        // 存储节点值和节点属性
        if(!nodeValue.isEmpty()){
            map.put(nodeName,nodeValue);
        }
        if(!attributes.isEmpty()){
            Map<String, Object> attributeMap = new HashMap<>();
            for (Attribute attribute : attributes) {
                attributeMap.put(attribute.getName(),attribute.getValue());
            }
            map.put(nodeName + "Attributes",attributeMap);
        }

        // 获取子节点
        List<Element> elements = element.elements();
        // 如果没有子节点，则直接返回
        if(elements.isEmpty()){
            return;
        }
        // 存储子节点
        Map<String,Object> childMap;
        for(Element e : elements){
            if(map.containsKey(e.getName())){
                if(map.get(e.getName()) instanceof List){
                    ((List) map.get(e.getName())).add(childMap = new HashMap<>());
                }else{
                    List<Object> tempList = new ArrayList<>();
                    tempList.add(map.get(e.getName()));
                    tempList.add(childMap = new HashMap<>());
                    map.put(e.getName(),tempList);
                }
            }else{
                map.put(e.getName(),childMap = new HashMap<>());
            }
            traverseNode(e,childMap);
        }
    }
}
